package top.korori.common.model;

import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import top.korori.common.enums.StatusCode;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static top.korori.common.enums.StatusCode.FAIL;
import static top.korori.common.enums.StatusCode.SUCCESS;


@ToString
@Getter
@Setter
@ApiModel("响应结果")
public class Result<T> {


    @ApiModelProperty("是否成功")
    private Boolean flag;

    @ApiModelProperty("状态码")
    private Integer code;

    @ApiModelProperty("消息")
    private String msg;

    @ApiModelProperty("数据")
    private T data;

    public static <T,R> Result<R> okAndToObj(T data,Class<R> rClass){
        R r = BeanUtil.copyProperties(data, rClass);
        return ok(r);
    }

    public static <T,R> Result<List<R>> okAndToList(List<T> data,Class<R> rClass){
        List<R> rs = BeanUtil.copyToList(data, rClass);
        return ok(rs);
    }


    public static <T> Result<Map<String,T>> okAndPut(String key, T data){
        Map<String,T> map = new HashMap<>();
        map.put(key,data);
        return ok(map);
    }

    public static <T> Result<T> ok() {
        return restResult(true, null, SUCCESS.getCode(), SUCCESS.getDesc());
    }

    public static <T> Result<T> ok(T data) {
        return restResult(true, data, SUCCESS.getCode(), SUCCESS.getDesc());
    }



    public static <T> Result<T> ok(T data, String msg) {
        return restResult(true, data, SUCCESS.getCode(), msg);
    }

    public static <T> Result<T> fail() {
        return restResult(false, null, FAIL.getCode(), FAIL.getDesc());
    }

    public static <T> Result<T> fail(StatusCode statusCode) {
        return restResult(false, null, statusCode.getCode(), statusCode.getDesc());
    }

    public static <T> Result<T> fail(String msg) {
        return restResult(false, msg);
    }

    public static <T> Result<T> fail(T data) {
        return restResult(false, data, FAIL.getCode(), FAIL.getDesc());
    }

    public static <T> Result<T> fail(T data, String msg) {
        return restResult(false, data, FAIL.getCode(), msg);
    }

    public static <T> Result<T> fail(Integer code, String msg) {
        return restResult(false, null, code, msg);
    }

    private static <T> Result<T> restResult(Boolean flag, String msg) {
        Result<T> apiResult = new Result<T>();
        apiResult.setFlag(flag);
        apiResult.setCode(flag ? SUCCESS.getCode() : FAIL.getCode());
        apiResult.setMsg(msg);
        return apiResult;
    }

    private static <T> Result<T> restResult(Boolean flag, T data, Integer code, String msg) {
        Result<T> apiResult = new Result<T>();
        apiResult.setFlag(flag);
        apiResult.setData(data);
        apiResult.setCode(code);
        apiResult.setMsg(msg);
        return apiResult;
    }

}
